function timestretch
[x,fs,nbits,opts]=wavread('broke_it.wav');
x=x-min(x);
x=x/max(x);
x=2*x-1;
%opts


sLeftMargin = 100;
sBottomMargin = 100;
sWidth = 100;
sHeight = 200;

sWinSizeVal = .25;
sWinSpeedVal = 1.0;
sDelayVal = 0;

maxSpeed=1.0;
maxDelay=1.0;

tWinSizeVal = 'window size';
tWinSpeedVal = 'window speed';
tDelayVal = 'delay';

tHeight = 30;
vGap = 5;
stepSmall = .0001;
stepBig = .001;
bDoneVal=0;
bWidth=80;
bHeight=40;

numSliders=3;

f = figure('Visible','off','Position',[sLeftMargin,sBottomMargin,2*sLeftMargin+(numSliders*2-1)*sWidth,2*sBottomMargin+sHeight],'MenuBar','none','Name','timestretch','NumberTitle','off','Resize','off');

    function sWinSize_Callback(source,eventdata)
        sWinSizeVal = get(source,'Value');
        set(tWinSize,'String',sprintf('%s:\n%g s',tWinSizeVal,sWinSizeVal));
    end

    function sWinSpeed_Callback(source,eventdata)
        sWinSpeedVal = get(source,'Value');
        set(tWinSpeed,'String',sprintf('%s:\n%g s/s',tWinSpeedVal,sWinSpeedVal));
    end

    function sDelay_Callback(source,eventdata)
        sDelayVal = get(source,'Value');
        set(tDelay,'String',sprintf('%s:\n%g s',tDelayVal,sDelayVal));
    end

    function bDone_Callback(source,eventdata)
        bDoneVal=1;
    end

sWinSize    = uicontrol(f,'Style','slider',...
    'Max',length(x)/fs,'Min',2/fs,'SliderStep',[stepSmall stepBig],...
    'Position',[sLeftMargin,sBottomMargin,sWidth,sHeight],...
    'Callback',{@sWinSize_Callback});
tWinSize = uicontrol(f,'Style','text',...
    'String',tWinSizeVal,...
    'Position',[sLeftMargin,sBottomMargin-tHeight-vGap,sWidth,tHeight]);
sWinSpeed    = uicontrol(f,'Style','slider',...
    'Max',maxSpeed,'Min',-maxSpeed,'SliderStep',[stepSmall stepBig],...
    'Position',[sLeftMargin+2*sWidth,sBottomMargin,sWidth,sHeight],...
    'Callback',{@sWinSpeed_Callback});
tWinSpeed = uicontrol(f,'Style','text',...
    'String',tWinSpeedVal,...
    'Position',[sLeftMargin+2*sWidth,sBottomMargin-tHeight-vGap,sWidth,tHeight]);
sDelay    = uicontrol(f,'Style','slider',...
    'Max',maxDelay,'Min',0.0,'SliderStep',[stepSmall stepBig],...
    'Position',[sLeftMargin+4*sWidth,sBottomMargin,sWidth,sHeight],...
    'Callback',{@sDelay_Callback});
tDelay = uicontrol(f,'Style','text',...
    'String',tDelayVal,...
    'Position',[sLeftMargin+4*sWidth,sBottomMargin-tHeight-vGap,sWidth,tHeight]);

tHeadLoc = uicontrol(f,'Style','text','Position',[(2*sLeftMargin+(2*numSliders-1)*sWidth)/2-sWidth/2 2*sBottomMargin+sHeight-5*tHeight/2 sWidth 2*tHeight]);
bDone = uicontrol(f,'Style','pushbutton','String','done','Position',[(2*sLeftMargin+(2*numSliders-1)*sWidth)-3*bWidth/2 bHeight/2 bWidth bHeight],...
    'Callback',{@bDone_Callback});
set(sWinSize,'Value',sWinSizeVal); sWinSize_Callback(sWinSize,[]); %bug that this isn't called automatically
set(sWinSpeed,'Value',sWinSpeedVal); sWinSpeed_Callback(sWinSpeed,[]); %bug that this isn't called automatically
set(sDelay,'Value',sDelayVal); sDelay_Callback(sDelay,[]); %bug that this isn't called automatically
set(f,'Visible','on')



%hw=daqhwinfo;
%hw.InstalledAdaptors;
%ws=daqhwinfo('winsound');
%ws.BoardNames;
%ws.InstalledBoardIds;
ao = analogoutput('winsound');
%get(ao)
set(ao,'SampleRate',fs);
chans = addchannel(ao,1:2); %starts with 0 for nidaqs
%get(ao.Channel(1))


numBuffs=2;
buffSecs=.1;
buffSize=round(buffSecs*fs);
buff=zeros(buffSize,1);
dBuff=buff;

delayBuffSize=round(maxDelay*fs);
delayBuff=zeros(delayBuffSize,1);

winLeft=1;
playHead=1;
delayBuffPos=1;
done=0;
while ~done
    for i=1:buffSize
        buff(i)=x(playHead);
        delayBuff(delayBuffPos)=x(playHead);
        
        if delayBuffPos-round(sDelayVal*fs)<1
            dBuff(i)=delayBuff(delayBuffPos-round(sDelayVal*fs)+delayBuffSize);
        else
            dBuff(i)=delayBuff(delayBuffPos-round(sDelayVal*fs));
        end
        
        if playHead>=length(x)
            playHead=1;
        elseif playHead>=winLeft+sWinSizeVal*fs || (playHead<winLeft && playHead>=sWinSizeVal*fs-(length(x)-winLeft))
            playHead=round(winLeft);
        else
            playHead=playHead+1;
        end
        
        winLeft=winLeft+sWinSpeedVal;
        if winLeft>length(x)
            winLeft=1;
        elseif winLeft<1
            winLeft=length(x);
        end
        
        if delayBuffPos>=delayBuffSize
            delayBuffPos=1;
        else
            delayBuffPos=delayBuffPos+1;
        end
    end

    set(tHeadLoc,'String',sprintf('%.4g s\n%.4g%%\n%.4g s\n%.4g%%',playHead/fs,100*playHead/length(x),winLeft/fs,100*winLeft/length(x)));
    
    putdata(ao,[buff dBuff]);
    if ~strcmp(get(ao,'Running'),'On') && get(ao,'SamplesAvailable')>0
        start(ao)
        disp('had to restart')
    end
    
    while get(ao,'SamplesAvailable')>numBuffs*buffSize && ~done
        %spin
        if bDoneVal
            done=1;
        end
    end
    drawnow
end

delete(ao);
end